from datetime import datetime
from pathlib import Path
from enum import Enum

class LogLevel(Enum):
    DEBUG = 'DEBUG'
    INFO = 'INFO'
    WARN = 'WARN'
    ERROR = 'ERROR'
    FATAL = 'FATAL'

class LogType(Enum):
    CONSOLE = 'CONSOLE'
    FILE = 'FILE'
    BOTH = 'BOTH'

class MyLogger:
    def __init__(self, logtype: LogType = LogType.BOTH, timeEnable: bool = True):
        self.logtype = logtype
        self.timeEnable = timeEnable
        self.fileHandle = None
        if logtype != LogType.CONSOLE:
            logpath = Path(__file__).resolve().parent.joinpath("logs")
            logpath.mkdir(parents=True, exist_ok=True)
            timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
            self.logfile = logpath.joinpath(f"bfats_{timestamp}.log")
            self.fileHandle = open(self.logfile, 'a+', encoding='utf-8')

    def __del__(self):
        if self.logtype != LogType.CONSOLE and self.fileHandle != None:
            self.fileHandle.close()

    def __logFile__(self, formatMsg: str):
        try:
            self.fileHandle.write(formatMsg + '\n')
            self.fileHandle.flush()
        except Exception as e:
            print(e)

    def __logConsole__(self, formatMsg: str):
        print(formatMsg)

    def log(self, level: LogLevel, message):
        if self.timeEnable:
            now = datetime.now()
            timestamp = f"{now.year}-{now.month:02d}-{now.day:02d} {now.hour:02d}:{now.minute:02d}:{now.second:02d}:{now.microsecond // 1000:03d}"
            msg = f"{timestamp} | {level.name} | {message}"
        else:
            msg = f"{timestamp} | {level.name} | {message}"
        if self.logtype == LogType.BOTH:
            self.__logConsole__(msg)
            self.__logFile__(msg)
        elif self.logtype == LogType.FILE:
            self.__logFile__(msg)
        else:
            self.__logConsole__(msg)

    def debug(self, message):
        self.log(LogLevel.DEBUG, message)

    def info(self, message):
        self.log(LogLevel.INFO, message)

    def warn(self, message):
        self.log(LogLevel.WARN, message)

    def error(self, message):
        self.log(LogLevel.ERROR, message)

    def fatal(self, message):
        self.log(LogLevel.FATAL, message)